home *** CD-ROM | disk | FTP | other *** search
/ Aminet 43 / Aminet 43 (2001)(GTI - Schatztruhe)[!][Jun 2001].iso / Aminet / game / think / Connect4.lha / Connect4 / source / gameboardclass.c < prev    next >
C/C++ Source or Header  |  2001-04-08  |  23KB  |  668 lines

  1. #include "gameboardclass.h"
  2. #include "graphics_support.h"
  3. #include "computer_player.h"
  4. #include <hardware/blit.h>
  5. #include <stdio.h>
  6.  
  7. // Uncomment this to debug
  8. //#define GAMEBOARDCLASS_DEBUG
  9.  
  10. __saveds ULONG gameboardDispatcher (__reg("a0") struct IClass *cl,
  11.                                     __reg("a2") Object *obj,
  12.                                     __reg("a1") Msg msg)
  13. {
  14.     switch (msg->MethodID)
  15.     {
  16.         case OM_NEW             : return(gameboardNew           (cl, obj, msg));
  17.         case OM_DISPOSE         : return(gameboardDispose       (cl, obj, msg));
  18.         case OM_SET             : return(gameboardSet           (cl, obj, (struct opSet *)msg));
  19.         case OM_GET             : return(gameboardGet           (cl, obj, (struct opGet *)msg));
  20.         case MUIM_Draw          : return(gameboardDraw          (cl, obj, (struct MUIP_Draw *)msg));
  21.         case MUIM_HandleInput   : return(gameboardHandleInput   (cl, obj, (struct MUIP_HandleInput *)msg));
  22.         case MUIM_Setup         : return(gameboardSetup         (cl, obj, (struct MUIP_Setup *)msg));
  23.         case MUIM_Cleanup       : return(gameboardCleanup       (cl, obj, (struct MUIP_CleanUp *)msg));
  24.         case MUIM_Gameboard_MakeMove  : return(gameboardMakeMove (cl,obj, msg));
  25.     }
  26.  
  27.     return (DoSuperMethodA(cl, obj, msg));
  28. }
  29.  
  30. __saveds ULONG gameboardNew (struct IClass *cl, Object *obj, Msg *msg)
  31. {
  32.     struct gameboarddata *gb_data;
  33.  
  34.     if (!(obj=(Object *)DoSuperMethodA(cl, obj, msg)))
  35.         return 0;
  36.  
  37.     gb_data=INST_DATA(cl, obj);
  38.  
  39.     // Initialise the columntop[] and filled[][] arrays to -1
  40.     {
  41.         int i, j;
  42.  
  43.         for (i=0; i<7; i++)
  44.         {
  45.             gb_data->columntop[i]=-1;
  46.             for (j=0; j<5; j++)
  47.                 gb_data->filled[i][j]=-1;
  48.         }
  49.     }
  50.     
  51.     gb_data->current_player=red_player; // red player goes first
  52.  
  53.     gb_data->inputactive=FALSE;         // Can't play until this is TRUE
  54.     gb_data->restartgameboard=FALSE;
  55.  
  56.     loadiff("PROGDIR:gfx/red_counter",    &gb_data->red_width,    &gb_data->red_height,    &gb_data->red_depth,    NULL, &gb_data->red_body,    &gb_data->red_palette);
  57.     loadiff("PROGDIR:gfx/yellow_counter", &gb_data->yellow_width, &gb_data->yellow_height, &gb_data->yellow_depth, NULL, &gb_data->yellow_body, &gb_data->yellow_palette);
  58.    
  59.     return ((ULONG)obj);
  60. }
  61.  
  62. __saveds ULONG gameboardDispose (struct IClass *cl, Object *obj, Msg *msg)
  63. {
  64.     struct gameboarddata *gb_data=INST_DATA(cl, obj);
  65.     
  66.     // Free everything that loadiff() allocated for us
  67.     free(gb_data->red_palette);
  68.     free(gb_data->red_body);
  69.  
  70.     free(gb_data->yellow_palette);
  71.     free(gb_data->yellow_body);
  72.  
  73.     return (DoSuperMethodA(cl, obj, msg));
  74. }
  75.  
  76.  
  77. __saveds ULONG gameboardSet (struct IClass *cl, Object *obj, struct opSet *msg)
  78. {
  79.     {
  80.         struct TagItem *ti, *tstate;
  81.         struct gameboarddata *gb_data=INST_DATA(cl, obj);
  82.  
  83.         ti=msg->ops_AttrList;
  84.         tstate=ti;
  85.     
  86.         while (ti = NextTagItem(&tstate))
  87.         {
  88.             switch (ti->ti_Tag)
  89.             {
  90.                 case MUIA_Gameboard_CurrentPlayer:
  91.                         gb_data->current_player=ti->ti_Data;
  92.                         /*
  93.                         ** FOR SOME REASON, THIS IS A BIG NO-NO!!!!!!!!!!!
  94.                         **
  95.                         // Build a message and send it to the Notify class (our superclass)
  96.                         {
  97.                             struct TagItem tt[2];
  98.  
  99.                             tt[0].ti_Tag=ti->ti_Tag;
  100.                             tt[1].ti_Data=ti->ti_Data;
  101.                             tt[2].ti_Tag=TAG_DONE;
  102.  
  103.                             DoSuperMethod(cl, obj, OM_NOTIFY, tt, msg->ops_GInfo, 0L);
  104.                         }
  105.                         */
  106.                         break;
  107.  
  108.                 case MUIA_Gameboard_Inputactive:
  109.                         gb_data->inputactive=ti->ti_Data;
  110.                         break;
  111.  
  112.                 case MUIA_Gameboard_Winner:
  113.                         gb_data->winning_player=ti->ti_Data;
  114.                         break;
  115.  
  116.                 case MUIA_Gameboard_Restart:
  117.                         gb_data->restartgameboard=ti->ti_Data;
  118.                         MUI_Redraw(obj, MADF_DRAWUPDATE);
  119.                         break;
  120.  
  121.                 case MUIA_Gameboard_Tiegame:
  122.                         gb_data->tiegame=ti->ti_Data;
  123.                         break;
  124.  
  125.                 case MUIA_Gameboard_RedPlayer:
  126.                         gb_data->opponent[red_player].type=ti->ti_Data;
  127.                         break;
  128.  
  129.                 case MUIA_Gameboard_YellowPlayer:
  130.                         gb_data->opponent[yellow_player].type=ti->ti_Data;
  131.                         break;
  132.  
  133.                 case MUIA_Gameboard_RedDetail:
  134.                         gb_data->opponent[red_player].data=ti->ti_Data;
  135.                         break;
  136.  
  137.                 case MUIA_Gameboard_YellowDetail:
  138.                         gb_data->opponent[yellow_player].data=ti->ti_Data;
  139.                         break;
  140.             }
  141.         }
  142.     }
  143.     return (DoSuperMethodA(cl, obj, (Msg)msg));
  144. }
  145.  
  146. __saveds ULONG gameboardGet (struct IClass *cl, Object *obj, struct opGet *msg)
  147. {
  148.     struct gameboarddata *gb_data=INST_DATA(cl, obj);
  149.  
  150.     switch (msg->opg_AttrID)
  151.     {
  152.         case MUIA_Gameboard_CurrentPlayer:
  153.             *(msg->opg_Storage)=gb_data->current_player;
  154.             return TRUE;
  155.  
  156.         case MUIA_Gameboard_RedPlayer:
  157.             *(msg->opg_Storage)=gb_data->opponent[red_player].type;
  158.             return TRUE;
  159.  
  160.         case MUIA_Gameboard_YellowPlayer:
  161.             *(msg->opg_Storage)=gb_data->opponent[yellow_player].type;
  162.             return TRUE;
  163.  
  164.         case MUIA_Gameboard_RedDetail:
  165.             *(msg->opg_Storage)=gb_data->opponent[red_player].data;
  166.             return TRUE;
  167.  
  168.         case MUIA_Gameboard_YellowDetail:
  169.             *(msg->opg_Storage)=gb_data->opponent[yellow_player].data;
  170.             return TRUE;
  171.     }
  172.  
  173.     return(DoSuperMethodA(cl, obj, (Msg)msg));
  174. }
  175.  
  176.  
  177. __saveds ULONG gameboardDraw (struct IClass *cl, Object *obj, struct MUIP_Draw *msg)
  178. {
  179.     DoSuperMethodA(cl, obj, (Msg)msg);
  180.  
  181.     if (msg->flags & MADF_DRAWOBJECT)
  182.     {
  183.         struct gameboarddata *gb_data=INST_DATA(cl, obj);
  184.         int column, row;
  185.  
  186.         for (column=0; column<7; column++)
  187.         {
  188.             for (row=0; row<5; row++)
  189.             {
  190.                 if (gb_data->filled[column][row]==red_player)
  191.                 {
  192.                     BltMaskBitMapRastPort(gb_data->red_bitmap, 0, 0, _rp(obj),
  193.                                           _mleft(obj)+13+(column*60)+7, _mtop(obj)+12+((4-row)*60)+7,
  194.                                           gb_data->red_width, gb_data->red_height,
  195.                                           (ABC|ABNC|ANBC), gb_data->mask_bitmap->Planes[0]);
  196.                 }
  197.                 else if (gb_data->filled[column][row]==yellow_player)
  198.                 {
  199.                     BltMaskBitMapRastPort(gb_data->yellow_bitmap, 0, 0, _rp(obj),
  200.                                           _mleft(obj)+13+(column*60)+7, _mtop(obj)+12+((4-row)*60)+7,
  201.                                           gb_data->yellow_width, gb_data->yellow_height,
  202.                                           (ABC|ABNC|ANBC), gb_data->mask_bitmap->Planes[0]);
  203.                 }
  204.             }
  205.         }
  206.     }
  207.     else if (msg->flags & MADF_DRAWUPDATE)
  208.     {
  209.         struct gameboarddata *gb_data=INST_DATA(cl, obj);
  210.         
  211.         if (gb_data->restartgameboard)
  212.         {
  213.             // Initialise the columntop[] and filled[][] arrays to -1
  214.             {
  215.                 int i, j;
  216.  
  217.                 for (i=0; i<7; i++)
  218.                 {
  219.                     gb_data->columntop[i]=-1;
  220.                     for (j=0; j<5; j++)
  221.                         gb_data->filled[i][j]=-1;
  222.                 }
  223.             }
  224.  
  225.             gb_data->current_player=red_player; // red player goes first
  226.             gb_data->inputactive=FALSE;         // Can't play until this is TRUE
  227.             gb_data->restartgameboard=FALSE;
  228.  
  229.             // Clear all the pieces
  230.             {
  231.                 int column, row;
  232.  
  233.                 for (column=0; column<7; column++)
  234.                 {
  235.                     for (row=0; row<5; row++)
  236.                     {
  237.                         BltMaskBitMapRastPort(gb_data->blank_bitmap, 0, 0, _rp(obj),
  238.                                               _mleft(obj)+13+(column*60)+7, _mtop(obj)+12+((4-row)*60)+7,
  239.                                               gb_data->blank_width, gb_data->blank_height,
  240.                                               (ABC|ABNC|ANBC), gb_data->mask_bitmap->Planes[0]);
  241.                     }
  242.                 }
  243.             }
  244.         }
  245.         else
  246.         {
  247.             if (gb_data->current_player==red_player)
  248.             {
  249.                 BltMaskBitMapRastPort(gb_data->red_bitmap, 0, 0, _rp(obj),
  250.                                       gb_data->counterx, gb_data->countery,
  251.                                       gb_data->red_width, gb_data->red_height,
  252.                                       (ABC|ABNC|ANBC), gb_data->mask_bitmap->Planes[0]);
  253.             }
  254.             else
  255.             {
  256.                 BltMaskBitMapRastPort(gb_data->yellow_bitmap, 0, 0, _rp(obj),
  257.                                       gb_data->counterx, gb_data->countery,
  258.                                       gb_data->yellow_width, gb_data->yellow_height,
  259.                                       (ABC|ABNC|ANBC), gb_data->mask_bitmap->Planes[0]);
  260.             }
  261.         }
  262.     }
  263.  
  264.     return 0;
  265. }
  266.  
  267. __saveds ULONG gameboardHandleInput (struct IClass *cl, Object *obj, struct MUIP_HandleInput *msg)
  268. {
  269.     #define _isbetween(a, x, b) ((x)>=(a) && (x)<=(b))
  270.     #define _isinobject(x, y) (_isbetween(_mleft(obj), (x), _mright(obj))  \
  271.                             && _isbetween(_mtop(obj), (y), _mbottom(obj)))
  272.  
  273.     struct gameboarddata *gb_data=INST_DATA(cl, obj);
  274.  
  275.     if (gb_data->inputactive)
  276.     {
  277.         if (msg->imsg)
  278.         {
  279.             if (msg->imsg->Class==IDCMP_MOUSEBUTTONS)
  280.             {
  281.                 if (msg->imsg->Code==SELECTDOWN)
  282.                 {
  283.                     if (_isinobject(msg->imsg->MouseX, msg->imsg->MouseY))
  284.                     {
  285.                         int column;
  286.  
  287.                         if ((column=msg->imsg->MouseX-_mleft(obj)-13)>=0)
  288.                         {
  289.                             column=column/60;
  290.  
  291.                             if (column>=0 && column<=6)
  292.                             {
  293.                                 if (gb_data->columntop[column]<4)
  294.                                 {
  295.                                     gb_data->column=column;
  296.                                     DoMethod(obj, MUIM_Gameboard_MakeMove);
  297.                                 }
  298.                             }
  299.                         }
  300.                     }
  301.                 }
  302.             }
  303.         }
  304.     }
  305.  
  306.     return 0;
  307. }
  308.  
  309. __saveds ULONG gameboardSetup (struct IClass *cl, Object *obj, struct MUIP_Setup *msg)
  310. {
  311.     if (!(DoSuperMethodA(cl, obj, (Msg)msg)))
  312.         return (FALSE);
  313.  
  314.     {
  315.         struct gameboarddata *gb_data=INST_DATA(cl, obj);
  316.         UBYTE mask_body[270] =
  317.         {
  318.             /* Plane 0 */
  319.             0x00, 0x00, 0x3F, 0xE0, 0x00, 0x00, 0x00, 0x01, 0xFF, 0xFC, 0x00, 0x00, 0x00, 0x0F, 0xFF, 0xFF,
  320.             0x80, 0x00, 0x00, 0x1F, 0xFF, 0xFF, 0xC0, 0x00, 0x00, 0x7F, 0xFF, 0xFF, 0xF0, 0x00, 0x00, 0xFF,
  321.             0xFF, 0xFF, 0xF8, 0x00, 0x01, 0xFF, 0xFF, 0xFF, 0xFC, 0x00, 0x03, 0xFF, 0xFF, 0xFF, 0xFE, 0x00,
  322.             0x07, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x0F, 0xFF, 0xFF, 0xFF, 0xFF, 0x80, 0x0F, 0xFF, 0xFF, 0xFF,
  323.             0xFF, 0x80, 0x1F, 0xFF, 0xFF, 0xFF, 0xFF, 0xC0, 0x3F, 0xFF, 0xFF, 0xFF, 0xFF, 0xE0, 0x3F, 0xFF,
  324.             0xFF, 0xFF, 0xFF, 0xE0, 0x3F, 0xFF, 0xFF, 0xFF, 0xFF, 0xE0, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xF0,
  325.             0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xF0, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xF0, 0xFF, 0xFF, 0xFF, 0xFF,
  326.             0xFF, 0xF8, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF8, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF8, 0xFF, 0xFF,
  327.             0xFF, 0xFF, 0xFF, 0xF8, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF8, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF8,
  328.             0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF8, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF8, 0xFF, 0xFF, 0xFF, 0xFF,
  329.             0xFF, 0xF8, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xF0, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xF0, 0x7F, 0xFF,
  330.             0xFF, 0xFF, 0xFF, 0xF0, 0x3F, 0xFF, 0xFF, 0xFF, 0xFF, 0xE0, 0x3F, 0xFF, 0xFF, 0xFF, 0xFF, 0xE0,
  331.             0x3F, 0xFF, 0xFF, 0xFF, 0xFF, 0xE0, 0x1F, 0xFF, 0xFF, 0xFF, 0xFF, 0xC0, 0x0F, 0xFF, 0xFF, 0xFF,
  332.             0xFF, 0x80, 0x0F, 0xFF, 0xFF, 0xFF, 0xFF, 0x80, 0x07, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x03, 0xFF,
  333.             0xFF, 0xFF, 0xFE, 0x00, 0x01, 0xFF, 0xFF, 0xFF, 0xFC, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xF8, 0x00,
  334.             0x00, 0x7F, 0xFF, 0xFF, 0xF0, 0x00, 0x00, 0x1F, 0xFF, 0xFF, 0xC0, 0x00, 0x00, 0x0F, 0xFF, 0xFF,
  335.             0x80, 0x00, 0x00, 0x01, 0xFF, 0xFC, 0x00, 0x00, 0x00, 0x00, 0x3F, 0xE0, 0x00, 0x00
  336.         };
  337.         UBYTE blank_body[270] =
  338.         {
  339.             /*Plane 0*/
  340.             0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
  341.             0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
  342.             0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
  343.             0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
  344.             0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
  345.             0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
  346.             0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
  347.             0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
  348.             0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
  349.             0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
  350.             0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
  351.             0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
  352.             0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
  353.             0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
  354.             0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
  355.             0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
  356.             0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF
  357.         };
  358.  
  359.         // Create red counter bitmap
  360.         gb_data->red_bitmap=bodytobitmap(gb_data->red_width, gb_data->red_height, gb_data->red_depth, gb_data->red_body);
  361.  
  362.         // Create yellow counter bitmap
  363.         gb_data->yellow_bitmap=bodytobitmap(gb_data->yellow_width, gb_data->yellow_height, gb_data->yellow_depth, gb_data->yellow_body);
  364.  
  365.         // Create counter mask bitmap
  366.         gb_data->mask_bitmap=bodytobitmap(45, 45, 1, mask_body);
  367.  
  368.         // Create blank square bitmap
  369.         gb_data->blank_width=45;
  370.         gb_data->blank_height=45;
  371.         gb_data->blank_depth=1;
  372.         gb_data->blank_bitmap=bodytobitmap(gb_data->blank_width, gb_data->blank_height, gb_data->blank_depth, blank_body);
  373.         // and set up its palette
  374.         {
  375.             int i;
  376.             for (i=0; i<3; i++)
  377.             {
  378.                 gb_data->blank_palette[i]  =0x00000000;
  379.                 gb_data->blank_palette[i+3]=0xFFFFFFFF;
  380.             }
  381.         }
  382.  
  383.         {
  384.             struct Screen *screen=_screen(obj);
  385.             int i;
  386.  
  387.             // Initialise allocated pen array
  388.             for (i=0; i<GAMEBOARD_PENS; i++)
  389.             {
  390.                 gb_data->pens[i].number=-1;
  391.                 gb_data->pens[i].red=0;
  392.                 gb_data->pens[i].green=0;
  393.                 gb_data->pens[i].blue=0;
  394.             }
  395.  
  396.             // Remap colours in red and yellow counter bitmaps
  397.             #ifdef GRAPHICS_SUPPORT_DEBUG
  398.             puts("##red bitmap");
  399.             #endif
  400.             remapbitmap(gb_data->red_bitmap, screen->ViewPort.ColorMap, gb_data->red_palette, gb_data->pens, GAMEBOARD_PENS);
  401.  
  402.             #ifdef GRAPHICS_SUPPORT_DEBUG
  403.             puts("##yellow bitmap");
  404.             #endif
  405.             remapbitmap(gb_data->yellow_bitmap, screen->ViewPort.ColorMap, gb_data->yellow_palette, gb_data->pens, GAMEBOARD_PENS);
  406.  
  407.             #ifdef GRAPHICS_SUPPORT_DEBUG
  408.             puts("##blank bitmap");
  409.             #endif
  410.             remapbitmap(gb_data->blank_bitmap, screen->ViewPort.ColorMap, gb_data->blank_palette, gb_data->pens, GAMEBOARD_PENS);
  411.         }
  412.  
  413.     }
  414.  
  415.     MUI_RequestIDCMP(obj, IDCMP_MOUSEBUTTONS);
  416.  
  417.     return (TRUE);
  418. }
  419.  
  420.  
  421. __saveds ULONG gameboardCleanup (struct IClass *cl, Object *obj, struct MUIP_CleanUp *msg)
  422. {
  423.     struct gameboarddata *gb_data=INST_DATA(cl, obj);
  424.     struct Screen *screen=_screen(obj);
  425.  
  426.     freeallocatedpens(screen->ViewPort.ColorMap, gb_data->pens, GAMEBOARD_PENS);
  427.  
  428.     FreeBitMap(gb_data->red_bitmap);
  429.     FreeBitMap(gb_data->yellow_bitmap);
  430.     FreeBitMap(gb_data->mask_bitmap);
  431.     FreeBitMap(gb_data->blank_bitmap);
  432.  
  433.     MUI_RejectIDCMP(obj, IDCMP_MOUSEBUTTONS);
  434.  
  435.     return (DoSuperMethodA(cl, obj, (Msg)msg));
  436. }
  437.  
  438. __saveds ULONG gameboardMakeMove (struct IClass *cl, Object *obj, Msg *msg)
  439. {
  440.     struct gameboarddata *gb_data=INST_DATA(cl, obj);
  441.     int row, column=gb_data->column;
  442.  
  443.     // Overide the imported column number if the current player is non-local
  444.     if (gb_data->opponent[gb_data->current_player].type==PlayerType_Computer)
  445.     {
  446.         gb_data->column=computer_player(1, NULL, gb_data->columntop, FALSE);
  447.         column=gb_data->column;
  448.     }
  449.  
  450.     row=gb_data->columntop[column]+1;
  451.     gb_data->columntop[column]++;
  452.  
  453.     gb_data->filled[column][row]=gb_data->current_player;
  454.  
  455.     #ifdef GAMEBOARDCLASS_DEBUG
  456.     {
  457.         char i, j;
  458.  
  459.         for (i=4; i>=0; i--)
  460.         {
  461.             for (j=0; j<7; j++)
  462.                 printf("%2.d ", gb_data->filled[j][i]);
  463.             printf("\n");
  464.         }
  465.         printf("\n");
  466.     }
  467.     #endif
  468.  
  469.  
  470.     gb_data->row=row;
  471.     gb_data->counterx=_mleft(obj)+13+(column*60)+7;
  472.     gb_data->countery=_mtop(obj)+12+((4-row)*60)+7;
  473.     MUI_Redraw(obj, MADF_DRAWUPDATE);
  474.     if (!testwinordraw(obj, gb_data))   // if the game isn't over, change player
  475.     {
  476.         if (gb_data->current_player==red_player)
  477.             SetAttrs(obj, MUIA_Gameboard_CurrentPlayer, yellow_player, TAG_DONE);
  478.         else
  479.             SetAttrs(obj, MUIA_Gameboard_CurrentPlayer, red_player, TAG_DONE);
  480.     }
  481.  
  482.     return 0;
  483. }
  484.  
  485.  
  486. BOOL testwinordraw (Object *obj, struct gameboarddata *gb_data)
  487. {
  488.     char result, winner=-1;
  489.     if ((result=testS(gb_data, gb_data->column, gb_data->row))>=0)
  490.         winner=result;
  491.  
  492.     if ((result=testWE(gb_data, gb_data->column, gb_data->row))>=0)
  493.         winner=result;
  494.  
  495.     if ((result=testNESW(gb_data, gb_data->column, gb_data->row))>=0)
  496.         winner=result;
  497.  
  498.     if ((result=testNWSE(gb_data, gb_data->column, gb_data->row))>=0)
  499.         winner=result;
  500.  
  501.     if (winner>=0)
  502.     {
  503.         SetAttrs(obj, MUIA_Gameboard_Winner, winner, TAG_DONE);
  504.         return TRUE;
  505.     }
  506.     else if (fullboard(gb_data))
  507.     {
  508.         SetAttrs(obj, MUIA_Gameboard_Tiegame, TRUE, TAG_DONE);
  509.         return TRUE;
  510.     }
  511.  
  512.     return FALSE;
  513. }
  514.  
  515. /* Test from current position->South
  516. **
  517. **                               +
  518. **                               |
  519. **
  520. ** RESULT:
  521. **          red_player or yellow_player, or -1 if no-one has won
  522. */
  523. char testS (struct gameboarddata *gb_data, int column, int row)
  524. {
  525.     if (row>=3)
  526.     {
  527.         char total, i;
  528.  
  529.         total=0;
  530.         for (i=row; i>=(row-3); i--)
  531.             total+=gb_data->filled[column][i];
  532.  
  533.         if (total==0)
  534.             return red_player;
  535.         else if (total==4)
  536.             return yellow_player;
  537.         else
  538.             return -1;
  539.     }
  540.     else
  541.         return -1;
  542. }
  543.  
  544. /* Test from current position->West and from current position->East
  545. **
  546. **                             --+--
  547. **
  548. ** RESULT:
  549. **          red_player or yellow_player, or -1 if no-one has won
  550. */
  551. char testWE (struct gameboarddata *gb_data, int column, int row)
  552. {
  553.     char total, i;
  554.  
  555.     total=0;
  556.     for (i=0; i<7; i++)
  557.     {
  558.         if (gb_data->filled[i][row]==gb_data->current_player)
  559.             total++;
  560.         else if (total>=4)
  561.             break;
  562.         else
  563.             total=0;
  564.         #ifdef GAMEBOARDCLASS_DEBUG
  565.         printf("WE total=%d\n", total);
  566.         #endif
  567.     }
  568.  
  569.     if (total>=4)
  570.         return gb_data->current_player;
  571.     else
  572.         return -1;
  573. }
  574.  
  575. /* Test from current position->NorthEast and from current position->SouthWest
  576. **
  577. **                                /
  578. **                               +
  579. **                              /
  580. **
  581. ** RESULT:
  582. **          red_player or yellow_player, or -1 if no-one has won
  583. */
  584. char testNESW(struct gameboarddata *gb_data, int column, int row)
  585. {
  586.     char diagrow=0;
  587.     char total=0;
  588.     char diagcolumn;
  589.  
  590.     for (diagcolumn=column-row; diagrow<5; diagcolumn++)
  591.     {
  592.         if (diagcolumn>=0 && diagcolumn<=6)
  593.         {
  594.             if (gb_data->filled[diagcolumn][diagrow]==gb_data->current_player)
  595.                 total++;
  596.             else if (total>=4)
  597.                 break;
  598.             else
  599.                 total=0;
  600.             #ifdef GAMEBOARDCLASS_DEBUG
  601.             printf("NESW total=%d\n", total);
  602.             #endif
  603.         }
  604.  
  605.         diagrow++;
  606.     }
  607.  
  608.     if (total>=4)
  609.         return gb_data->current_player;
  610.     else
  611.         return -1;
  612. }
  613.  
  614. /* Test from current position->NorthWest and from current position->SouthEast
  615. **
  616. **                              \
  617. **                               +
  618. ++                                \
  619. **
  620. ** RESULT:
  621. **          red_player or yellow_player, or -1 if no-one has won
  622. */
  623. char testNWSE(struct gameboarddata *gb_data, int column, int row)
  624. {
  625.     char diagrow=0;
  626.     char total=0;
  627.     char diagcolumn;
  628.  
  629.     for (diagcolumn=column+row; diagrow<5; diagcolumn--)
  630.     {
  631.         if (diagcolumn>=0 && diagcolumn<=6)
  632.         {
  633.             if (gb_data->filled[diagcolumn][diagrow]==gb_data->current_player)
  634.                 total++;
  635.             else if (total>=4)
  636.                 break;
  637.             else
  638.                 total=0;
  639.             #ifdef GAMEBOARDCLASS_DEBUG
  640.             printf("NWSE total=%d\n", total);
  641.             #endif
  642.         }
  643.  
  644.         diagrow++;
  645.     }
  646.  
  647.     if (total>=4)
  648.         return gb_data->current_player;
  649.     else
  650.         return -1;
  651.     
  652. }
  653.  
  654.  
  655. BOOL fullboard(struct gameboarddata *gb_data)
  656. {
  657.     char i;
  658.  
  659.     for (i=0; i<7; i++)
  660.     {
  661.         if (gb_data->filled[i][4]==-1)
  662.             return FALSE;
  663.     }
  664.     return TRUE;    // If we get to this, the board is full!
  665. }
  666.  
  667.  
  668.